package com.lan.service.sys.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lan.SysConstants;
import com.lan.businessObject.MapBo;
import com.lan.entity.sys.Role;
import com.lan.entity.sys.RoleMenu;
import com.lan.entity.sys.UserRoleRel;
import com.lan.mapper.sys.RoleMapper;
import com.lan.mapper.sys.RoleMenuMapper;
import com.lan.mapper.sys.UserRoleMapper;
import com.lan.service.sys.RoleService;
import com.lan.service.sys.UserRoleService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author shadow
 * @since 2022-06-04
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Resource
    private RoleMapper roleMapper;
    @Resource
    private UserRoleMapper relUserRoleMapper;
    @Resource
    private RoleMenuMapper roleMenuRelMapper;
    @Resource
    private UserRoleService userRoleService;

    /**
     * 当前存在的 角色名 & 角色码
     */
    @Override
    public List<MapBo> getRoleList() {
        List<MapBo> mapBoList = new ArrayList<>();
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        List<Role> roleList = roleMapper.selectList(wrapper);
        roleList.forEach(x -> {
            MapBo mapBo = new MapBo();
            mapBo.setName(x.getName()).setValue(x.getCode());
            mapBoList.add(mapBo);
        });
        return mapBoList;
    }

    @Override
    public List<Role> getRoleListByUserId(final String userId) {
        if (null != userId && 0 < userId.length()) {
            // 用户id -> 角色list
            UserRoleRel relUserRole = new UserRoleRel();
            relUserRole.setUserId(userId);
            List<UserRoleRel> relUserRoleList = getList(relUserRole);
            // 用户角色关联list -> 角色id list
            Set<String> roleSet = new HashSet<>();
            relUserRoleList.forEach(x -> roleSet.add(x.getRoleId()));
            if (!roleSet.isEmpty()) {
                QueryWrapper<Role> query = new QueryWrapper<>();
                query.in("id", roleSet);
                query.eq(SysConstants.STATUS,"1");
                return roleMapper.selectList(query);
            }
        }
        return Collections.emptyList();
    }

    @Override
    public List<Role> getListByWrapper(final Role role) {
        return getList(role, new QueryWrapper<>());
    }

    @Override
    public Role getRoleByCode(String code) {
        if (null != code && code.length() > 0) {
            Role role = new Role();
            role.setCode(code);
            List<Role> roleList = getListByWrapper(role);
            if (CollectionUtils.isNotEmpty(roleList)) {
                return roleList.get(0);
            }
        }
        return null;
    }

    @Override
    public int setUserRole(final String userId, final List<String> roleList) {
        userRoleService.deleteByUserId(userId);
        roleList.forEach(x -> {
            Role roleByCode = getRoleByCode(x);
            UserRoleRel userRoleRel = new UserRoleRel();
            userRoleRel.setId(UUID.randomUUID().toString())
                    .setUserId(userId)
                    .setRoleId(roleByCode.getId());
            relUserRoleMapper.insert(userRoleRel);
        });
        return 1;
    }

    @Override
    public void config(final String roleId, final String menuArr) {
        //更新 角色
        Role role = roleMapper.selectById(roleId);
        role.setUpdated(LocalDateTime.now());
        roleMapper.updateById(role);
        //更新 角色-菜单 配置
        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        roleMenuRelMapper.delete(wrapper);
        if (StringUtils.isNotBlank(menuArr)) {
            for (String i : menuArr.split(",")) {
                RoleMenu roleMenuRel = new RoleMenu();
                roleMenuRel.setRoleId(roleId).setMenuId(i).setCreated(LocalDateTime.now()).setUpdated(LocalDateTime.now());
                roleMenuRelMapper.insert(roleMenuRel);
            }
        }

    }

    /**
     * 角色 通用查询
     *
     * */
    private List<Role> getList(Role role, QueryWrapper<Role> query) {
        Optional.ofNullable(role.getId()).filter(StringUtils::isNotBlank).ifPresent(x -> query.eq("id", x));
        Optional.ofNullable(role.getCode()).filter(StringUtils::isNotBlank).ifPresent(x -> query.eq("code", x));
        Optional.ofNullable(role.getName()).filter(StringUtils::isNotBlank).ifPresent(x -> query.eq("name", x));
        Optional.ofNullable(role.getStatus()).filter(StringUtils::isNotBlank).ifPresent(x -> query.eq("status", x));
        query.eq("status", "1")
             .orderByDesc("created");
        return roleMapper.selectList(query);
    }

    /**
     * 用户角色关联 通用查询
     *
     * */
    private List<UserRoleRel> getList(UserRoleRel relUserRole) {
        QueryWrapper<UserRoleRel> query = new QueryWrapper<>();
        Optional.ofNullable(relUserRole.getId()).filter(StringUtils::isNotBlank).ifPresent(x -> query.eq("id", x));
        Optional.ofNullable(relUserRole.getUserId()).filter(StringUtils::isNotBlank).ifPresent(x -> query.eq("user_id", x));
        Optional.ofNullable(relUserRole.getRoleId()).filter(StringUtils::isNotBlank).ifPresent(x -> query.eq("role_id", x));
        return relUserRoleMapper.selectList(query);
    }

}
